#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <conio.h>

#pragma comment(lib, "ws2_32.lib")

#define BUFFER_SIZE 2048
#define SERVER_PORT 8888

// 初始化Winsock库
int init_winsock() {
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        printf("WSAStartup失败: %d\n", WSAGetLastError());
        return 0;
    }
    return 1;
}

// 连接到服务器
SOCKET connect_to_server(const char* server_ip, int port) {
    SOCKET client_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (client_socket == INVALID_SOCKET) {
        printf("创建套接字失败: %d\n", WSAGetLastError());
        return INVALID_SOCKET;
    }

    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);

    // 将IP地址从字符串转换为二进制格式
    if (inet_pton(AF_INET, server_ip, &server_addr.sin_addr) <= 0) {
        printf("无效的服务器地址\n");
        closesocket(client_socket);
        return INVALID_SOCKET;
    }

    if (connect(client_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) == SOCKET_ERROR) {
        printf("连接服务器失败: %d\n", WSAGetLastError());
        closesocket(client_socket);
        return INVALID_SOCKET;
    }

    printf("已连接到服务器 %s:%d\n", server_ip, port);
    return client_socket;
}

// 发送昵称到服务器
void send_nickname(SOCKET client_socket, const char* nickname) {
    send(client_socket, nickname, strlen(nickname), 0);
}

// 接收消息线程函数
DWORD WINAPI receive_messages(LPVOID lpParam) {
    SOCKET client_socket = (SOCKET)lpParam;
    char buffer[BUFFER_SIZE];
    int recv_len;

    while (1) {
        recv_len = recv(client_socket, buffer, sizeof(buffer) - 1, 0);
        if (recv_len <= 0) {
            printf("与服务器断开连接\n");
            break;
        }

        buffer[recv_len] = '\0';
        printf("%s\n", buffer);
    }

    return 0;
}

// 清理资源
void cleanup(SOCKET client_socket) {
    closesocket(client_socket);
    WSACleanup();
}

int main(int argc, char* argv[]) {
    char server_ip[16] = "127.0.0.1"; // 默认连接本地服务器
    int port = SERVER_PORT;
    char nickname[32];
    char message[BUFFER_SIZE];
    SOCKET client_socket;
    HANDLE thread;
    DWORD thread_id;

    // 检查命令行参数
    if (argc > 1) {
        strncpy(server_ip, argv[1], sizeof(server_ip) - 1);
    }
    if (argc > 2) {
        port = atoi(argv[2]);
    }

    // 初始化Winsock
    if (!init_winsock()) {
        return 1;
    }

    // 获取用户昵称
    printf("请输入您的昵称: ");
    fgets(nickname, sizeof(nickname), stdin);
    
    // 移除昵称末尾的换行符
    size_t len = strlen(nickname);
    if (len > 0 && nickname[len - 1] == '\n') {
        nickname[len - 1] = '\0';
    }

    // 连接到服务器
    client_socket = connect_to_server(server_ip, port);
    if (client_socket == INVALID_SOCKET) {
        WSACleanup();
        return 1;
    }

    // 发送昵称
    send_nickname(client_socket, nickname);

    // 创建接收消息线程
    thread = CreateThread(NULL, 0, receive_messages, (LPVOID)client_socket, 0, &thread_id);
    if (thread == NULL) {
        printf("创建接收线程失败: %d\n", GetLastError());
        cleanup(client_socket);
        return 1;
    }

    printf("聊天开始! 输入消息发送，输入'/quit'退出\n");

    // 主循环处理用户输入
    while (1) {
        // 改用 fgets 直接获取输入，避免 _kbhit() 和 _getch() 对中文的支持问题
        printf("请输入消息: ");
        fgets(message, sizeof(message), stdin);
        
        // 移除消息末尾的换行符
        len = strlen(message);
        if (len > 0 && message[len - 1] == '\n') {
            message[len - 1] = '\0';
        }
    
        // 检查是否退出
        if (strcmp(message, "/quit") == 0) {
            printf("正在断开连接...\n");
            break;
        }
    
        // 发送消息到服务器
        if (send(client_socket, message, strlen(message), 0) == SOCKET_ERROR) {
            printf("发送消息失败: %d\n", WSAGetLastError());
            break;
        }
        // 不需要 Sleep，因为 fgets 会阻塞直到用户输入
    }

    // 清理
    TerminateThread(thread, 0);
    CloseHandle(thread);
    cleanup(client_socket);

    printf("已退出聊天室\n");
    return 0;
}